home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / lib / yotpin / src / magsave.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-21  |  14.4 KB  |  639 lines

  1. /*
  2. *    Yamana's Otomeza Plug-in Tool
  3. *        MAGセーバ
  4. *    
  5. *    1995.07.17    
  6. *    1995.07.26    2倍程度の高速化
  7. *    1995.08.06    メモリの浪費を抑えるためバッファのページ化を行った
  8. *    1995.08.09    乙女座V1.3b 仕様に変更
  9. *    1995.08.13    ページ化を強化しメモリ不足に対処
  10. *    
  11. *    バグ
  12. *        ・フラグBのサイズが大きくなる。なんで??
  13. *    
  14. *    "MAG" (c) Woddy-RINN
  15. */
  16.  
  17. #include    "otome_pi.h"
  18.  
  19. const char    longname[] = "FILE  : まぐせーば";
  20. const char    extend[] = "MAG";
  21.  
  22. #define        USE_FILE    PI_SAVE
  23. #include    "otome_pi.c"
  24.  
  25.                     /*  01234567012340123456789012345678 */
  26. char    MAG_check[]  = "MAKI02  TOWN >謎<               ";
  27. char    def_comment[]= "MAGSAVER/OTOMEZA";
  28.  
  29. #define        POS_USER    13
  30. #define        LEN_USER    18
  31. #define        LEN_TOPDATA    (8+4+1+LEN_USER+1)
  32.  
  33. typedef struct
  34. {    
  35.     char    head;
  36.     char    machine;
  37.     char    machine_dat;
  38.     char    screen;
  39.     short    sx;
  40.     short    sy;
  41.     short    ex;
  42.     short    ey;
  43.     long    flgA;
  44.     long    flgB;
  45.     long    flgB_size;
  46.     long    pixel;
  47.     long    pixel_size;
  48. }MagHeader;
  49.  
  50. char    *user='\0',*comment='\0';
  51.  
  52. extern char    *my_getenv();
  53.  
  54. #define    MAX_PIXPAGESIZE        (32*1024)
  55. int     pixPageSize= MAX_PIXPAGESIZE;
  56. int     pixPage    = 0;
  57.  
  58. int     flgBPageSize= MAX_PIXPAGESIZE;
  59. int     flgBPage    = 0;
  60.  
  61. char    *mem,*flg[2],*flgA,**flgB,**pixel;
  62.  
  63. /**********************************************************************/
  64. /*** 圧縮用メモリ確保 ***/
  65.  
  66. int MAG_mallocBuffers( vramWidth,Height )
  67. int     vramWidth,Height;
  68. {
  69.     extern void freePixBuf();
  70.     
  71.     if( (mem=PI_MALLOC(
  72.                  (vramWidth+8)*2            /* 作業用フラグバッファ */
  73.                 +(vramWidth*Height+7)/8+8    /* フラグA */
  74.             ))==NULL )
  75.     {
  76.         return PI_ERROR_NO_MEMORY;
  77.     }
  78.     if( mallocPixBuf( vramWidth,Height ) )
  79.     {    PI_FREE( mem );
  80.         return PI_ERROR_NO_MEMORY;
  81.     }
  82.     if( mallocFlgBBuf( vramWidth,Height ) )
  83.     {    freePixBuf();
  84.         PI_FREE( mem );
  85.         return PI_ERROR_NO_MEMORY;
  86.     }
  87.     
  88.     /* メモリ割り当て */
  89.     flg[0]= mem ;
  90.     flg[1]= mem + (vramWidth+8) ;
  91.     flgA  = mem + (vramWidth+8)*2 ;
  92.     
  93.     return NOERR;
  94. }
  95.  
  96. void MAG_freeBuffers()
  97. {    
  98.     extern void freePixBuf();
  99.     
  100.     PI_FREE( mem );
  101.     freePixBuf();
  102.     
  103. }
  104.  
  105. /****** MAG フォーマット圧縮部 ******/
  106.  
  107. int     MAG_encode( head,buf )
  108. MagHeader    *head;
  109. char        *buf;
  110. {
  111.     char Bit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  112.     
  113.     /* フラグのチェック順序で圧縮効率が左右される */
  114. #if 0
  115.     char flgOrder[] = { 0,1,4,5,6,7,9,10,2,8,11,12,13,14,3,15 };
  116.     char flgTable[][2] =
  117.     {    { 0, 0},
  118.         { 2, 0},{ 0, 1},{ 2, 1},{ 0, 2},{ 2, 2},    /*  1, 4, 5, 6, 7 */
  119.         { 0, 4},{ 2, 4},{ 4, 0},{ 4, 2},{ 4, 4},    /*  9,10, 2, 8,11 */
  120.         { 0, 8},{ 2, 8},{ 4, 8},{ 8, 0},{ 0,16}     /* 12,13,14, 3,15 */
  121.     };
  122. #else    /* こっちは yamana-a オリジナルの順番 */
  123.     char flgOrder[] = { 0,1,4,2,6,5,7,9,8,10,11,12,13,14,3,15 };
  124.     char flgTable[][2] =
  125.     {    { 0, 0},
  126.         { 2, 0},{ 0, 1},{ 4, 0},{ 0, 2},{ 2, 1},    /*  1, 4, 5, 6, 7 */
  127.         { 2, 2},{ 0, 4},{ 4, 2},{ 2, 4},{ 4, 4},    /*  9,10, 2, 8,11 */
  128.         { 0, 8},{ 2, 8},{ 4, 8},{ 8, 0},{ 0,16}     /* 12,13,14, 3,15 */
  129.     };
  130. #endif
  131.     
  132.     int     Width,Height, flgWidth, vramWidth, realWidth;
  133.     int     i,j;
  134.     register int    x,y,x1,y1;
  135.     int     p0,p1, upper;
  136.     int     flgAi,flgBi,pixi;
  137.     
  138.     realWidth    = (head->ex - head->sx +1 );
  139.     Height        = (head->ey - head->sy +1 );
  140.     
  141.     /***
  142.         16色
  143.         2ドット=1バイト
  144.         4ドット=2バイト=1ピクセル
  145.         8ドット=4バイト=2ピクセル=1フラグ
  146.         
  147.         256色
  148.         1ドット=1バイト
  149.         2ドット=2バイト=1ピクセル
  150.         4ドット=4バイト=2ピクセル=1フラグ
  151.     ***/
  152.     
  153.     /* バッファには32ドット単位で格納されているので注意 */
  154.     if( head->screen == 0 )
  155.     {    vramWidth    =((realWidth+31)& 0xffe0)>>1 ;
  156.         Width         =((realWidth+ 7)& 0xfff8)>>1 ;    /* 8ドット単位で記録 */
  157.         head->ex    = (head->sx + (Width<<1) - 1);
  158.     }else
  159.     {    vramWidth    = (realWidth+31)& 0xffe0 ;
  160.         Width        = (realWidth+ 7)& 0xfff8 ;    /* ほんとは4ドット単位だが */
  161.         head->ex    = (head->sx + Width - 1);    /* この際だから統一させる  */
  162.     }
  163.     flgWidth = Width>>2 ;                /* フラグ単位のときの幅 */
  164.     
  165.     if( MAG_mallocBuffers( vramWidth,Height ) )
  166.         return ERROR;
  167.     
  168.     /******** フラグデータ作成 ********/
  169.     
  170.     pixi = flgAi = flgBi = 0;
  171.     flgA[0] = 0;
  172.     for( y=0; y<Height ; y++ )
  173.     {
  174.         for( x=0; x<Width; x+=2 )
  175.             flg[y & 1][ x>>2 ] = 0;            /* 1フラグ=2ピクセル=4バイト*/
  176.         
  177.         for( x=0; x<Width; x+=2 )            /* 2バイト単位 */
  178.         {    
  179. #if 0
  180.             if( x+4 >= Width )                /* 右端の4バイトについては */
  181.             {    j = (x+2)-realWidth/2;        /* 黒の塗りつぶしチェック */
  182.                 if( j > 1 )
  183.                     p0 = 0,                    /* ゴミが出ないよう埋める  */
  184.                     WORD( buf + x + y*vramWidth ) = 0;
  185.                 else if( j==1 )
  186.                     p0 = BYTE( buf + x + y*vramWidth ),
  187.                     WORD( buf + x + y*vramWidth ) &= 0x00ff ;
  188.                 else
  189.                     p0 = WORD( buf + x + y*vramWidth );
  190.             }else
  191. #endif
  192.             p0 = WORD( buf + x + y*vramWidth );
  193.             
  194.             for( i=1; i<16; i++ )        /* 同じピクセルを探す */
  195.             {    
  196.                 x1= (x - flgTable[i][0]);
  197.                 y1= (y - flgTable[i][1]);
  198.                 if( x1<0 || y1<0 )    continue;
  199.                 
  200.                 p1 = WORD( buf + x1 + y1*vramWidth );
  201.                 
  202.                 /* 近くに同じピクセルがある? */
  203.                 if( p0 == p1 )
  204.                 {    flg[ y&1 ][ x>>2 ]
  205.                         |= ( (int)flgOrder[i] << (((x & 2)==0)? 4:0 ));
  206.                     break;
  207.                 }
  208.             }
  209.             if( i==16 )        /* 見つからないときは、その点を記録 */
  210.             {    
  211.                 if( pixi >= pixPageSize )        /* ページ切替え */
  212.                 {    if( remallocPixBuf() )
  213.                         return PI_ERROR_NO_MEMORY;
  214.                     pixi = 0;
  215.                 }
  216.                 if( head->screen )    /* 256色 */
  217.                 {    pixel[pixPage][ pixi++ ] = ( p0     & 0xff);
  218.                     pixel[pixPage][ pixi++ ] = ((p0>>8) & 0xff);
  219.                 }else
  220.                 {    /* 上位下位入替え */
  221.                     p1 = (( p0 & 0xf0f0 )>>4 );
  222.                     p0 = (( p0 & 0x0f0f )<<4 );
  223.                     p0 |= p1 ;
  224.                     
  225.                     pixel[pixPage][ pixi++ ] = (char)( p0    );
  226.                     pixel[pixPage][ pixi++ ] = (char)((p0>>8));
  227.                     
  228.                 }
  229.             }
  230.         }/* x<Width */
  231.         
  232.         /*  ここまでで1ラインぶんのフラグ作成完了    */
  233.         /*  続いてフラグA、Bを作成する            */
  234.         
  235.         for ( x=0; x< flgWidth; x++ )
  236.         {    
  237.             if( y>0 )    /* 上のラインとXORをとる */
  238.                 upper = (flg[y & 1][x] ^ flg[(y-1) & 1][x] );
  239.             else
  240.                 upper = (flg[y & 1][x] );
  241.             
  242.             if( upper != 0 )
  243.             {    /* flgA は 8ビット単位なので、ビットカウンタflgAiの */
  244.                 /* 下位3ビットは無視する */
  245.                 flgA[ flgAi>>3] |= Bit[ flgAi & 7 ] ;
  246.                 
  247.                 if( flgBi >= flgBPageSize )        /* ページ切替え */
  248.                 {    if( remallocFlgBBuf() )
  249.                         return PI_ERROR_NO_MEMORY;
  250.                     flgBi = 0;
  251.                 }
  252.                 flgB[flgBPage][ flgBi++ ]  = upper ;
  253.             }
  254.             if( (flgAi & 7)== 7 )        /* 次のフラグを初期化 */
  255.                 flgA[ (flgAi>>3)+1 ] = 0 ;
  256.             
  257.             flgAi++;
  258.             
  259.         }
  260.     }/* y<Height */
  261.     
  262.     flgAi = (flgAi+7)/8 ;        /* flgAi はビットカウンタ */
  263.     if( flgAi & 1 )    flgAi++;
  264.     if( flgBi & 1 )    flgBi++;
  265.     
  266.     
  267.     /** ヘッダの書換えを行う **/
  268.     
  269.     head->flgA        = (sizeof(MagHeader)+(head->screen==0 ? 16*3:256*3));
  270.     head->flgB        = (head->flgA + flgAi);
  271.     head->flgB_size    = (flgBPage*flgBPageSize + flgBi);
  272.     head->pixel        = (head->flgB + head->flgB_size);
  273.     head->pixel_size= (pixPage*pixPageSize + pixi);
  274.     
  275.     return NOERR;
  276. }
  277.  
  278. /*********************************************/
  279. /*    ピクセルデータのページ管理
  280. **
  281. **    MAG エンコードのとき圧縮後のデータを格納するため、最悪の場合 vram と
  282. **    同じ大きさのピクセル用メモリが必要となる。
  283. **    ただし、最悪の場合を想定していては無駄なメモリを増加させるだけなので
  284. **    ページ単位でメモリを確保し、足りなくなったら追加確保するようにする。
  285. **    
  286. */
  287.  
  288. void freePixBuf()
  289. {
  290.     int i;
  291.     
  292.     for( i=0; i<=pixPage; i++ )
  293.         PI_FREE( pixel[i] );
  294.     PI_FREE( pixel );
  295. }
  296.  
  297. int mallocPixBuf( Width,Height )
  298. int     Width,Height;
  299. {
  300.     int     all,page;
  301.     
  302.     all  = Width * Height ;                /* 全画面データに必要なメモリ */
  303.     page = (all / pixPageSize )+1 ;        /* 最大ページサイズ */
  304.     
  305.     if( (pixel=(char**)PI_MALLOC( sizeof(char*)*page ))==NULL )
  306.         return ERROR;
  307.     
  308.     /* 1ページだけ確保 */
  309.     if( (pixel[0] = (char*)PI_MALLOC( pixPageSize + 2 ))==NULL )
  310.     {    free( pixel );
  311.         return ERROR;
  312.     }
  313.     
  314.     return NOERR;
  315. }
  316.  
  317. int remallocPixBuf()
  318. {
  319.     if( (pixel[pixPage+1] = (char*)PI_MALLOC( pixPageSize + 2 ))==NULL )
  320.     {    freePixBuf();
  321.         return ERROR;
  322.     }
  323.     pixPage++;
  324.     return NOERR;
  325. }
  326.  
  327. /** flgB バッファのメモリ対策 **/
  328.  
  329. void freeFlgBBuf()
  330. {
  331.     int i;
  332.     
  333.     for( i=0; i<=flgBPage; i++ )
  334.         PI_FREE( flgB[i] );
  335.     PI_FREE( flgB );
  336. }
  337.  
  338. int mallocFlgBBuf( Width,Height )
  339. int     Width,Height;
  340. {
  341.     int     all,page;
  342.     
  343.     all  = Width * Height ;                /* 全画面データに必要なメモリ */
  344.     page = (all / flgBPageSize )+1 ;        /* 最大ページサイズ */
  345.     
  346.     if( (flgB=(char**)PI_MALLOC( sizeof(char*)*page ))==NULL )
  347.         return ERROR;
  348.     
  349.     /* 1ページだけ確保 */
  350.     if( (flgB[0] = (char*)PI_MALLOC( flgBPageSize + 2 ))==NULL )
  351.     {    free( flgB );
  352.         return ERROR;
  353.     }
  354.     
  355.     return NOERR;
  356. }
  357.  
  358. int remallocFlgBBuf()
  359. {
  360.     if( (flgB[flgBPage+1] = (char*)PI_MALLOC( flgBPageSize + 2 ))==NULL )
  361.     {    freeFlgBBuf();
  362.         return ERROR;
  363.     }
  364.     flgBPage++;
  365.     return NOERR;
  366. }
  367.  
  368. /**********************************************************************/
  369.  
  370. int MAG_head( head,palette,fr,pal )
  371. char        *palette;
  372. MagHeader    *head;
  373. FRAME        *fr;
  374. char        *pal;
  375. {
  376.     int     i,j,col;
  377.     char    *p;
  378.     
  379.     /** ファイル識別部分 **/
  380.     
  381.     p = '\0';
  382.     if( user != '\0' )    p = user;
  383.                 else    p = my_getenv("USER");
  384.     
  385.     if( p != '\0' )
  386.     {    for( i=0; i<LEN_USER && p[i]!='\0' ; i++ )    /* ユーザ名 */
  387.             MAG_check[ POS_USER+i ] = p[i];
  388.         for(    ; i<LEN_USER ; i++ )
  389.             MAG_check[ POS_USER+i ] = ' ';
  390.     }
  391.     
  392.     /** ヘッダ **/
  393.     
  394.     head->head         = 0x00;
  395.     head->machine     = 0x00;
  396.     head->machine_dat= 0x00;
  397.     head->sx = fr->lupx;
  398.     head->sy = fr->lupy;
  399.     head->ex = fr->rdwx;    /* ←圧縮の際に必要なのでまだ変更しない! */
  400.     head->ey = fr->rdwy;
  401.     
  402.     if( (col = DWORD(pal))!=16 && col!=256 )
  403.         return ERROR;
  404.     
  405.     if( col<256 )    head->screen = 0x00;
  406.             else    head->screen = 0x80;
  407.     
  408.     /*** パレットデータ ***/
  409.     
  410.     for( i=0,j=8; i<col; i++,j+=8 )
  411.     {
  412.         palette[ i*3   ] = pal[ j+2 ] ;        /* G */
  413.         palette[ i*3+1 ] = pal[ j+1 ] ;        /* R */
  414.         palette[ i*3+2 ] = pal[ j   ] ;     /* B */
  415.     }
  416.     
  417.     return NOERR;
  418. }
  419.  
  420. int MAG_writeBuffers( fp,head,palette )
  421. FILE        *fp;
  422. MagHeader    *head;
  423. char        *palette;
  424. {
  425.     int     i;
  426.     char    *p;
  427.     
  428.     /****/
  429.     
  430.     i = strlen( MAG_check );
  431.     if( i != fwrite( MAG_check, 1, i, fp) )
  432.         return ERROR;
  433.     
  434.     if( comment == '\0' )    p = def_comment;
  435.                     else    p = comment;
  436.     fwrite( p, 1, strlen(p), fp);
  437.     fputc( '\x1a' , fp);
  438.     
  439.     /****/
  440.     
  441.     fwrite( head,  sizeof(MagHeader), 1, fp);
  442.     fwrite( palette, 1, (head->screen ==0 ? 16*3:256*3) ,fp);
  443.     
  444.     /****/        /* ここまで慎重にならなくてよいかも */
  445.     
  446.     i = (head->flgB - head->flgA);
  447.     if( i != fwrite( flgA, 1, i, fp) )
  448.         return ERROR;
  449.     
  450.     for( i=0; i<flgBPage; i++ )
  451.         if( flgBPageSize != fwrite( &flgB[i][0], 1, flgBPageSize, fp ) )
  452.             return ERROR;
  453.     if( (i = head->flgB_size % flgBPageSize) >0 )
  454.         if( i != fwrite( &flgB[flgBPage][0], 1, i, fp ) )
  455.             return ERROR;
  456.     
  457.     for( i=0; i<pixPage; i++ )
  458.         if( pixPageSize != fwrite( &pixel[i][0], 1, pixPageSize, fp ) )
  459.             return ERROR;
  460.     if( (i = head->pixel_size % pixPageSize) >0 )
  461.         if( i != fwrite( &pixel[pixPage][0], 1, i, fp ) )
  462.             return ERROR;
  463.     
  464.     return NOERR;
  465. }
  466.  
  467. int     MAG_save( fp, buf,fr,pix,pal )
  468. char    *buf,*pal;
  469. FILE    *fp;
  470. int     pix;
  471. FRAME    *fr;
  472. {
  473.     int     ret;
  474.     int     col;
  475.     
  476.     MagHeader    head;
  477.     char        *palette;
  478.     
  479.     col = ((pix==8) ? 256 : 16);
  480.     
  481.     /* パレット用メモリ確保 */
  482.     if( (palette = PI_MALLOC( 3*col ))==NULL )
  483.         return PI_ERROR_NO_MEMORY;
  484.     
  485.     /*** ヘッダ作成 ***/
  486.     if( MAG_head( &head, palette,fr,pal ) )
  487.     {    free(palette);
  488.         return ERROR ;
  489.     }
  490.     /*** 圧縮 ***/
  491.     
  492.     ret = MAG_encode( &head, buf );
  493.     if( ret!=NOERR )
  494.         goto savequit;
  495.     
  496.     /*** 書き出し ***/
  497.     
  498.     ret = MAG_writeBuffers( fp, &head, palette );
  499.     
  500. savequit:
  501.     PI_FREE( palette );
  502.     MAG_freeBuffers();
  503.     
  504.     return ret;
  505. }
  506.  
  507.  
  508. /**********************************************************************/
  509. /** プラグイン呼び出し関数 **/
  510.  
  511. int     APL_exec()
  512. {
  513.     FILE    *fp;
  514.     int     ret;
  515.     FRAME    fr;
  516.     
  517.     if( pi_imge->pix >8 ) return NOERR;
  518.     
  519.     fr.lupx = fr.lupy = 0;
  520.     fr.rdwx = pi_imge->size.x-1;
  521.     fr.rdwy = pi_imge->size.y-1;
  522.     
  523.     
  524. //    if( my_getenv("USER")==NULL )
  525.     MAG_setComment();
  526.     
  527.     /**/
  528.     if( (fp=fopen( PI_FNAME,"wb" ))==NULL )
  529.         return PI_ERROR_FILE_OPEN;
  530.     
  531.     ret=MAG_save( fp, pi_imge->image ,    &fr,
  532.                       pi_imge->pix,
  533.                       pi_imge->clut );
  534.     
  535.     fclose( fp );
  536.     
  537.     if( ret )    remove( PI_FNAME );
  538.     /**/
  539.     
  540.     if( user    != '\0' )    PI_FREE( user );
  541.     if( comment != '\0' )    PI_FREE( comment );
  542.     return ret;
  543. }
  544.  
  545.  
  546.  
  547. /*************************************************************/
  548. /*    乙女座から得たコメントを分解する    */
  549.  
  550. #define    iskanji(c)    ( (0x81<=(c) && (c)<=0x9f) || (0xe0<=(c) && (c)<=0xfc))
  551. #define    iskanji2(c)    ( (0x40<=(c) && (c)<=0x7e) || (0x80<=(c) && (c)<=0xfc))
  552.  
  553. int MAG_setComment()
  554. {
  555.     int     i,j,len;
  556.     
  557.     if( PI_COMMENT==NULL || (len=strlen( PI_COMMENT ))<1 )
  558.         return NOERR;
  559.     
  560.     /* 面倒なのでメモリチェックは無視。これくらいで失敗するかな?? */
  561.     
  562.     for( i=0,j=0; i < LEN_USER ; i++ )
  563.     {    if( PI_COMMENT[i]==',' )
  564.         {    user=PI_MALLOC( i+1 );
  565.             strncpy( user, PI_COMMENT, i ),user[i]='\0';
  566.             
  567.             for( i++;i<len; i++ )
  568.                 if( PI_COMMENT[i]!=' ' && PI_COMMENT[i]!='\t' )    break;
  569.             if( i<len )
  570.             {    comment=PI_MALLOC( len-i+2 );
  571.                 strcpy( comment, PI_COMMENT+i );
  572.             }
  573.             return NOERR;
  574.         }
  575.     }
  576.     user=PI_MALLOC( LEN_USER+1 );
  577.     if( len> LEN_USER )
  578.         comment=PI_MALLOC( len - LEN_USER +1);
  579.     else
  580.     {    strcpy( user, PI_COMMENT );
  581.         return NOERR;
  582.     }
  583.     j=0;
  584.     /* 区切りに漢字コードが重なっている場合  念のため処理しておく */
  585.     if( iskanji( PI_COMMENT[ LEN_USER-1 ] )
  586.          && iskanji2( PI_COMMENT[ LEN_USER ] ) )
  587.         j = 1;
  588.     strncpy( user,        PI_COMMENT, LEN_USER-j );user[LEN_USER-j]='\0';
  589.     strcpy ( comment,    PI_COMMENT+ LEN_USER-j );
  590.     
  591. }
  592.  
  593. /**********************************************************************
  594. **    環境変数を取得する
  595. **    
  596. **    プラグイン内部からは getenv 関数によって環境変数が獲得できないので
  597. **    TOS_getPath 関数により獲得する。
  598. **    ただしこの関数は High-C のマニュアルでは全く触れられていない!
  599. **    
  600. **    int TOS_getPath( char *buf, const char *name, int len )
  601. **        buf  格納用バッファ(十分な大きさが必要)
  602. **        name 得たい環境変数名(末尾に '=' も追加しておくこと)
  603. **        len  name の文字長
  604. **    返り値
  605. **        実際に得た文字長。存在しなかったとき 0 となる。
  606. **        ただしこの関数はパスを得るものであるため、末尾が'\\'でない場合には
  607. **        勝手に'\\'が追加される。(漢字コードの区別は行われていない)
  608. **        また、環境変数名と'='は区別されないので、name に'='を追加しておか
  609. **        ないと'='も変数の内容として返される。
  610. */
  611.  
  612. #define    ENV_MAX        80
  613.  
  614. char    *my_getenv( name )
  615. char    *name;
  616. {
  617.     char    envbuf[ ENV_MAX+1 ];
  618.     int     i;
  619.     
  620.     /* '='で始まって末尾に '\\' を追加したものが返される */
  621.     if( (i=TOS_getPath( envbuf, name, strlen(name) ))==0 )
  622.         return NULL;
  623.     
  624.     if( i>2 )
  625.     {    if( !iskanji( envbuf[i-2] ) )    /* 漢字コード2バイト目でない */
  626.             envbuf[i-1] = '\0';
  627.     }
  628.     else if( i>0 )
  629.         envbuf[i-1] = '\0';
  630.     
  631.     if( i<1 || (user = PI_MALLOC( strlen( &envbuf[1] )+1 ))==NULL )
  632.         return '\0';
  633.     
  634.     strcpy( user, &envbuf[1] );        /* '=' のぶんスキップ */
  635.     
  636.     return user;
  637. }
  638.  
  639.